package com.media.module.utils;

import static android.content.Context.WINDOW_SERVICE;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.Formatter;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Environment;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.Toast;

public class CameraUtils {
	private static Formatter formatter;

	/**
	 * 时间格式化
	 *
	 * @param timeMs
	 * @return
	 */
	public static String timeFormat(int timeMs) {
		int totalSeconds = timeMs * 1000;

		int seconds = totalSeconds % 60;
		int minutes = (totalSeconds / 60) % 60;
		int hours = totalSeconds / 3600;
		StringBuilder sb = new StringBuilder();
		formatter = new Formatter(sb, Locale.getDefault());
		if (hours > 0) {
			return formatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
		} else {
			return formatter.format("%02d:%02d", minutes, seconds).toString();
		}
	}

	@SuppressLint("SimpleDateFormat")
	public static String thisTime(long time) {
		Date date = new Date(time);
		java.text.SimpleDateFormat f = new java.text.SimpleDateFormat("mm:ss");
		String timestring = f.format(date);
		return timestring;
	}

	@SuppressLint("SimpleDateFormat")
	public static String thisTime(double time) {
		Date date = new Date((long) time);
		java.text.SimpleDateFormat f = new java.text.SimpleDateFormat("mm:ss");
		String timestring = f.format(date);
		return timestring;
	}

	public static String getModifyTime() {
		// long l = file.lastModified();
		long l = System.currentTimeMillis();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss");
		Date date = new Date(l);
		String s = format.format(date);
		return s;
	}

	public static void turnLightOn(Camera mCamera) {
		if (mCamera == null) {
			return;
		}
		Parameters parameters = mCamera.getParameters();
		if (parameters == null) {
			return;
		}
		List<String> flashModes = parameters.getSupportedFlashModes();
		// Check if camera flash exists
		if (flashModes == null) {
			// Use the screen as a flashlight (next best thing)
			return;
		}
		String flashMode = parameters.getFlashMode();
		if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) {
			// Turn on the flash
			if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
				parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
				mCamera.setParameters(parameters);
			}
		}
	}

	public static void turnLightOff(Camera mCamera) {
		if (mCamera == null) {
			return;
		}
		Parameters parameters = mCamera.getParameters();
		if (parameters == null) {
			return;
		}
		List<String> flashModes = parameters.getSupportedFlashModes();
		String flashMode = parameters.getFlashMode();

		if (flashModes == null) {
			return;
		}
		if (!Parameters.FLASH_MODE_OFF.equals(flashMode)) {
			if (flashModes.contains(Parameters.FLASH_MODE_OFF)) {
				parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
				mCamera.setParameters(parameters);
			}

		}
	}

	public static Point getBestCameraResolution(Camera.Parameters parameters, Point screenResolution) {
		float tmp = 0f;
		float mindiff = 100f;
		float x_d_y = (float) screenResolution.x / (float) screenResolution.y;
		Size best = null;
		List<Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
		for (Size s : supportedPreviewSizes) {
			tmp = Math.abs(((float) s.height / (float) s.width) - x_d_y);
			if (tmp < mindiff) {
				mindiff = tmp;
				best = s;
			}
		}
		return new Point(best.width, best.height);
	}

	public static String getSDPath(Context context) {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory();
		} else if (!sdCardExist) {

			Toast.makeText(context, "SD卡不存在", Toast.LENGTH_SHORT).show();

		}
		File eis = new File(sdDir.toString() + "/Video/");
		try {
			if (!eis.exists()) {
				eis.mkdir();
			}
		} catch (Exception e) {

		}
		return sdDir.toString() + "/Video/";

	}

	public static String getSDPath(Context context, String path) {
		File sdDir = null;
		boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
		if (sdCardExist) {
			sdDir = Environment.getExternalStorageDirectory();
		} else if (!sdCardExist) {

			Toast.makeText(context, "SD卡不存在", Toast.LENGTH_SHORT).show();

		}
		File eis = new File(sdDir.toString() + "/" + path + "/");
		try {
			if (!eis.exists()) {
				eis.mkdir();
			}
		} catch (Exception e) {

		}
		return sdDir.toString() + "/" + path + "/";

	}

	public int getCamaraBackId() {

		int numberOfCameras = Camera.getNumberOfCameras();

		CameraInfo cameraInfo = new CameraInfo();
		for (int i = 0; i < numberOfCameras; i++) {
			Camera.getCameraInfo(i, cameraInfo);
			if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
				return i;
			}
		}
		return -1; // Device do not have back camera !!!!???
	}

	public static int getPreviewOrientation(Context context, int cameraId) {

		int temp = 0;
		int previewOrientation = 0;

		Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
		Camera.getCameraInfo(cameraId, cameraInfo);

		int deviceOrientation = getDeviceOrientation(context);
		temp = cameraInfo.orientation - deviceOrientation + 360;
		previewOrientation = temp % 360;

		return previewOrientation;
	}

	public static int getDeviceOrientation(Context context) {

		int degrees = 0;
		WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		int rotation = windowManager.getDefaultDisplay().getRotation();

		switch (rotation) {
		case Surface.ROTATION_0:
			degrees = 0;
			break;
		case Surface.ROTATION_90:
			degrees = 90;
			break;
		case Surface.ROTATION_180:
			degrees = 180;
			break;
		case Surface.ROTATION_270:
			degrees = 270;
			break;
		}

		return degrees;
	}
	
	/** 
     * Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000. 
     */  
	public static Rect calculateTapArea(Camera mCamera,float x, float y, float coefficient) {  
        float focusAreaSize = 300;  
        int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();  
  
        int centerX = (int) (x / getResolution(mCamera).width * 2000 - 1000);  
        int centerY = (int) (y / getResolution(mCamera).height * 2000 - 1000);  
  
        int left = clamp(centerX - areaSize / 2, -1000, 1000);  
        int right = clamp(left + areaSize, -1000, 1000);  
        int top = clamp(centerY - areaSize / 2, -1000, 1000);  
        int bottom = clamp(top + areaSize, -1000, 1000);  
  
        return new Rect(left, top, right, bottom);  
        }  
  
    private static int clamp(int x, int min, int max) {  
        if (x > max) {  
            return max;  
        }  
        if (x < min) {  
            return min;  
        }  
        return x;  
    }  
      
    public static Camera.Size getResolution(Camera mCamera) {  
        Camera.Parameters params = mCamera.getParameters();   
        Camera.Size s = params.getPreviewSize();  
        return s;  
    }  
    public static void setFocusMode (Context item, int type ,Camera mCamera){  
        Camera.Parameters params = mCamera.getParameters();   
        List<String> FocusModes = params.getSupportedFocusModes();  
  
        switch (type){  
        case 0:  
            if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))  
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);  
            else   
                Toast.makeText(item, "Auto Mode not supported", Toast.LENGTH_SHORT).show();  
            break;  
        case 1:           
            if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))  
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);  
            else  
                Toast.makeText(item, "Continuous Mode not supported", Toast.LENGTH_SHORT).show();  
            break;  
        case 2:           
            if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_EDOF))  
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_EDOF);  
            else  
                Toast.makeText(item, "EDOF Mode not supported", Toast.LENGTH_SHORT).show();  
            break;  
        case 3:  
            if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_FIXED))  
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);  
            else  
                Toast.makeText(item, "Fixed Mode not supported", Toast.LENGTH_SHORT).show();  
            break;  
        case 4:  
            if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_INFINITY))  
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);  
            else  
                Toast.makeText(item, "Infinity Mode not supported", Toast.LENGTH_SHORT).show();  
            break;  
        case 5:  
            if (FocusModes.contains(Camera.Parameters.FOCUS_MODE_MACRO))  
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);  
            else  
                Toast.makeText(item, "Macro Mode not supported", Toast.LENGTH_SHORT).show();  
            break;        
        }  
  
        mCamera.setParameters(params);  
    }  
      
    public static void setFlashMode (Camera mCamera ,Context item, int type){  
        Camera.Parameters params = mCamera.getParameters();  
        List<String> FlashModes = params.getSupportedFlashModes();  
  
        switch (type){  
        case 0:  
            if (FlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO))  
                params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);  
            else  
                Toast.makeText(item, "Auto Mode not supported", Toast.LENGTH_SHORT).show();  
            break;  
        case 1:  
            if (FlashModes.contains(Camera.Parameters.FLASH_MODE_OFF))  
                params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);  
            else  
                Toast.makeText(item, "Off Mode not supported", Toast.LENGTH_SHORT).show();            
            break;  
        case 2:  
            if (FlashModes.contains(Camera.Parameters.FLASH_MODE_ON))  
                params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);  
            else  
                Toast.makeText(item, "On Mode not supported", Toast.LENGTH_SHORT).show();         
            break;  
        case 3:  
            if (FlashModes.contains(Camera.Parameters.FLASH_MODE_RED_EYE))  
                params.setFlashMode(Camera.Parameters.FLASH_MODE_RED_EYE);  
            else  
                Toast.makeText(item, "Red Eye Mode not supported", Toast.LENGTH_SHORT).show();            
            break;  
        case 4:  
            if (FlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH))  
                params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);  
            else  
                Toast.makeText(item, "Torch Mode not supported", Toast.LENGTH_SHORT).show();          
            break;  
        }  
  
        mCamera.setParameters(params);  
    }  
  
    private static int getCameraId(boolean useFrontCamera) {
		int count = Camera.getNumberOfCameras();
		int result = -1;

		if (count > 0) {
			result = 0;

			Camera.CameraInfo info = new Camera.CameraInfo();
			for (int i = 0; i < count; i++) {
				Camera.getCameraInfo(i, info);

				if ((info.facing == 0) &&
						(!useFrontCamera)) {
					result = i;
					break;
				}if ((info.facing == 1) &&
						(useFrontCamera)) {
					result = i;
					break;
				}
			}
		}
		return result;
	}

	private static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
		double ASPECT_TOLERANCE = 0.1D;
		double targetRatio = (double)w / (double)h;
		if (sizes == null) {
			return null;
		} else {
			Camera.Size optimalSize = null;
			double minDiff = 1.7976931348623157E308D;
			int targetHeight = h;
			Iterator var13 = sizes.iterator();

			Camera.Size size;
			while(var13.hasNext()) {
				size = (Camera.Size)var13.next();
				double ratio = (double)size.width / (double)size.height;
				if (Math.abs(ratio - targetRatio) <= 0.1D && (double)Math.abs(size.height - targetHeight) < minDiff) {
					optimalSize = size;
					minDiff = (double)Math.abs(size.height - targetHeight);
				}
			}

			if (optimalSize == null) {
				minDiff = 1.7976931348623157E308D;
				var13 = sizes.iterator();

				while(var13.hasNext()) {
					size = (Camera.Size)var13.next();
					if ((double)Math.abs(size.height - targetHeight) < minDiff) {
						optimalSize = size;
						minDiff = (double)Math.abs(size.height - targetHeight);
					}
				}
			}

			return optimalSize;
		}
	}

	private static List<Camera.Size>  getMatchPreviewSizes(List<Camera.Size> supportedPreviewSizes, Camera.Size pictureSize) {
		List<Camera.Size> supportSizes = new ArrayList();
		Iterator var5 = supportedPreviewSizes.iterator();

		while(var5.hasNext()) {
			Camera.Size size = (Camera.Size)var5.next();
			if (size.height * pictureSize.width == pictureSize.height * size.width) {
				supportSizes.add(size);
			}
		}

		return supportSizes;
	}

	@SuppressLint("NewApi")
	public static List<Camera.Size> getPictureSizes (Context mContext){
		List<Camera.Size>  pictureSIzes = new ArrayList<Size>();
		List<Camera.Size> supportedPictureSizes  ;
		List<Camera.Size> supportedPreviewSizes ;
		Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
		Camera.getCameraInfo( getCameraId(false), cameraInfo);
		Camera camera = Camera.open( getCameraId(false));
		Camera.Parameters params = camera.getParameters();
		supportedPictureSizes = params.getSupportedPictureSizes();
		supportedPreviewSizes = params.getSupportedPreviewSizes();

		Size[] sizeArr = supportedPictureSizes.toArray(new Size[supportedPictureSizes.size()]);
		for (int i = 0; i < sizeArr.length -1; i++) {
			for (int j = 0; j < sizeArr.length -1; j++) {
				if(sizeArr[j].width > sizeArr[j + 1].width){
					Size size = sizeArr[j];
					sizeArr[j] = sizeArr[j + 1];
					sizeArr[j + 1] = size;
				}
			}
		}
		supportedPictureSizes = Arrays.asList(sizeArr);
		WindowManager windowManager = (WindowManager)mContext.getSystemService(WINDOW_SERVICE);
		Display display = windowManager.getDefaultDisplay();
		for(Camera.Size size : supportedPictureSizes){
			if(pictureSIzes.size()==5)break;
			if(size.height>=720&&getOptimalPreviewSize(getMatchPreviewSizes(supportedPreviewSizes,size),display.getWidth(),display.getHeight())!=null)pictureSIzes.add(size);
		}
		return  pictureSIzes;
	}

	public static int  minScale(int a, int b) {
		int tmp = a;
		int c = 1;
		if(a > b) {
			tmp = b;
		}
		for(int i = tmp; i > 0; i--) {
			if(a % i == 0 && b % i ==0) {
				c = i;
				break;
			}
		}
		return  c;
	}
    
    
}
